const PubSub = (function () {
  const topics = {}; // 用于存储主题和订阅的回调函数  {content: [{token: token, callback: (channel, data) => {console.log('ccc')}}]}

  // 订阅主题
  function subscribe(topic, callback) {
    if (!topics[topic]) {
      topics[topic] = []; // 如果主题不存在，则创建一个新的数组
    }
    const token = Symbol(); // 生成一个唯一标识符作为订阅的令牌
    topics[topic].push({ token, callback }); // 将令牌和回调函数添加到主题的订阅列表中

    return token; // 返回订阅的令牌
  }

  // 取消订阅
  function unsubscribe(token) {
    Object.keys(topics).forEach(topic => {
      const subscriptions = topics[topic];
      const index = subscriptions.findIndex(subscription => subscription.token === token); // 查找匹配令牌的订阅项的索引
      if (index > -1) {
        subscriptions.splice(index, 1); // 从订阅列表中移除匹配的订阅项
        if (subscriptions.length === 0) {
          delete topics[topic]; // 如果主题的订阅列表为空，则从主题中删除该属性
        }
      }
    });
  }

  // 发布消息
  function publish(topic, data) {
    if (topics[topic]) {
      topics[topic].forEach(x => {
        x.callback(data); // 调用订阅项的回调函数处理消息
      });
    }
  }

  // 返回 PubSub 对象，包含订阅、取消订阅和发布方法
  return {
    subscribe,
    unsubscribe,
    publish
  };
})();

// 示例用法
function handleNotification(data) {
  console.log('Received notification:', data);
}

const token = PubSub.subscribe('notifications', handleNotification); // 订阅名为 "notifications" 的主题，并提供处理通知的回调函数

PubSub.publish('notifications', 'New message'); // 发布名为 "notifications" 的主题的消息，传递数据 "New message" 给订阅的回调函数
// 输出: "Received notification: New message"

PubSub.unsubscribe(token); // 取消订阅特定的主题

PubSub.publish('notifications', 'Another message'); // 再次发布名为 "notifications" 的主题的消息，传递数据 "Another message" 给订阅的回调函数
// 没有输出，因为已经取消订阅